
from nerd.compute.latex_parser import LaTeXFormulaParser
from nerd.compute.expr_semantics import ExpressionSemantics
from pattern.collection import Numbered
import urllib2
import re
from pattern.error_handling import Safe



class Environment(object):
    
    COGS = "http://latex.codecogs.com/gif.download"
    
    
    class Formula(object):
        
        FORMULA = "formula"
        CONSTANT = "constant"

        COLORS = r"\definecolor{orange}{rgb}{1,0.5,0}"\
                 r"\definecolor{darkgreen}{rgb}{0,0.5,0}"

        def __init__(self, environment, data_object, label=None):
            self.environment = environment
            self.expression_string = data_object.content
            self.data_object = data_object
            self.label = label
            if hasattr(data_object, 'name'):
                self.kind = self.CONSTANT
                self.name = data_object.name
            else:
                self.kind = self.FORMULA
            
        @property
        def expression(self):
            e = self.expression_string
            if e.endswith("="): e = e[:-1]
            return self.environment.formula_parser(e)
        
        @property
        def value(self):
            return self.environment.semantics.evaluate(self.expression) 
        
        @property
        def entry(self):
            if self.kind == self.CONSTANT:
                return self.name + '=' + self.expression_string
            else:
                return self.expression_string
        
        def brief(self):
            if self.kind == self.CONSTANT:
                return self.COLORS + \
                    r"{\color{darkgreen} %s}{\color{orange} \,=\,}%s" % \
                    (self.name, self.expression_string)
            else:
                e = self.expression_string
                if e.endswith("="):
                    return self.COLORS + \
                        r"%s{\color{orange} \,=\,}{\color{blue} %s}" %\
                         (e[:-1], str(Safe(self).value))
                else:
                    return e
 
    def __init__(self, formulas, notebook_id=None):
        self.formulas = [self.Formula(self, x, i)
                          for (i, x) in Numbered(formulas)]
        self.formula_parser = LaTeXFormulaParser()
        self.semantics = ExpressionSemantics()
        self.notebook_id = notebook_id
        self.on_click_operation = "toggle_edit"
        #self.user_formulas = userfrms 
    
    def list_formulas(self):
        a = ["<li kind='%s' key='%s' entry='%s'>%s</li>" % 
             (fr.kind, fr.data_object.key(), fr.entry,
              Safe(fr).brief())
             for fr in self.formulas]
        return "<ul>%s</ul>" % "".join(a)
    
    def format_formulas(self):
        return "".join(["<ul>\n"
                        "  <li><img src=\"%s?{\\color{blue}%s}\"/></li>\n"
                        "  <ul>\n"
                        "    <li><em>source</em>: %s</li>\n"
                        "    <li><em>expression</em>: %s</li>\n"
                        "    <li><em>value</em>: %r</li>\n"
                        "  </ul>\n"
                        "</ul>\n"
                        "<hr/>\n" %
                        (self.COGS, fr.brief(), fr.expression_string,
                         Safe(fr).expression, Safe(fr).value)
                for fr in self.formulas])       
        
    def format_formulas_brief(self):
        return \
               "\n".join(['<p onclick="%(onclick)s(%(label)d)">'\
                          '<span style="font-size: 9pt; vertical-align: top">'\
                          '[%(label)d]</span> '\
                          '<img src="%(COGS)s?%(latex)s"/></p>'\
                          '<div id="%(label)d" style="visibility: hidden"></div>'
                           % {'COGS': self.COGS, 
                              'latex': fr.brief(),
                              'label': fr.label,
                              'onclick': self.on_click_operation}
                          for fr in self.formulas]) \
             + "\n"
         
    def _js(self):
        dictionary = dict((fr.label, {'source': str(fr.expression_string),
                                      'key': str(fr.data_object.key())})
                          for fr in self.formulas)
        return """
<script type='text/javascript'>
function toggle_edit(label)
{
    d = document.getElementById(label)
    if (d.style.visibility == "hidden") {
        d.innerHTML = %(edit_form)s
        d.style.visibility = "visible"
    }
    else {
        d.innerHTML = ''
        d.style.visibility = "hidden"
    }
}
function clear()
{
    document.getElementById('expression').value=''
}
function delete_()
{
    clear()
    submit()
}
formulas = %(dictionary)s
</script>
        """ % {'edit_form': self.EditForm(self),
               'dictionary': dictionary }
    
    def GetPlot(self,formula):
        wolfUrl = "http://www.wolframalpha.com/input/?" 
        data = urllib2.urlopen("http://www.wolframalpha.com/input/?i=" + formula).read()
        reg = "asynchronousPod\\('(.*?)', ?'0200',.*\\)"
        m = re.search(reg,data)
        return (wolfUrl + m.group(1))
        
        
    
    class EditForm(object):
        
        def __init__(self, environment):
            self.environment = environment
        
        def __str__(self):
            return """
            '<form action="/update" method="post">' +
            '<input name="notebook" type="hidden" value="%(notebook_id)s"/>'+
            '<input name="key" type="hidden" value="' +
                            formulas[label].key + '"/>' +
            '<input id="expression" name="expression" type="entry" value="' + 
                          formulas[label].source + '"/>' +
            '<input type="submit" value="ok"/>' +
            '<input id="delete" type="button" value="delete" onclick="document.getElementById(\\'expression\\').value=\\'\\'; submit()"/>' +
            '</form>'
            """ % {'notebook_id': self.environment.notebook_id}
        

         
